/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.je.meta.service.common;

import com.je.common.base.DynaBean;
import com.je.common.base.entity.func.FuncRelationField;
import com.je.core.entity.extjs.JSONTreeNode;

import java.util.List;
import java.util.Map;

/**
 * 元数据Bean服务
 */
public interface MetaBeanService {

    /**
     * 根据表编码得到表的描述性信息
     * @param tableCode
     * @return
     */
    DynaBean getResourceTable(String tableCode);

    /**
     * 根据表定义的编码得到对应的主键字段名称列表
     * @param dynaBean
     * @return
     */
    String getPKeyFieldNames(DynaBean dynaBean);

    /**
     * 根据表定义的编码得到对应的主键字段名称列表
     * @param tableCode
     * @return
     */
    String getPKeyFieldNames(String tableCode);

    /**
     * 获取当前表外键字段CODE
     * @param tableCode
     * @param parentTableCode
     * @param parentPkCode
     * @param relatedFields
     * @return
     */
    String getForeignKeyField(String tableCode, String parentTableCode, String parentPkCode, List<FuncRelationField> relatedFields);

    /**
     * 得到动态类的所有属性的名称
     * @param dynaBean
     * @return
     */
    String[] getNames(DynaBean dynaBean);

    /**
     * 得到动态类所有的属性名称,中间用","分开
     * @param table
     * @return
     */
    String getNames4Sql(DynaBean table);

    /**
     * 得到修改信息的sql语句段
     * @param resourceTable
     * @param values
     * @return
     */
    String getUpdateInfos4Sql(DynaBean resourceTable, Map values);

    /**
     * 得到动态类所有的属性名称,中间用","分开
     * @param dynaBean
     * @return
     */
    String getNames2DynaBean4Sql(DynaBean dynaBean);

    /**
     * 得到动态类的所有属性名称,格式化成 :name ,:age 的样子用于Sql
     * @param table
     * @return
     */
    String getValues4Sql(DynaBean table);

    /**
     * 根据ResourceTable得到DynaBean的结构
     * @param table
     * @return
     */
    DynaBean getDynaBeanByResourceTable(DynaBean table);

    /**
     * 得到动态类的所有值的内容
     * @param dynaBean
     * @return
     */
    Object[] getValues(DynaBean dynaBean);

    /**
     * 将更新字符串josn构建成list的dynaBean集合
     * @param updateStr
     * @param tableCode
     * @return
     */
    List<DynaBean> buildUpdateList(String updateStr,String tableCode);

    /**
     * 获取dynaBean的id数组  便于查询
     * @param beans
     * @param pkCode
     * @return
     */
    String[] getDynaBeanIdArray(List<DynaBean> beans,String pkCode);

    /**
     * 初始化资源表 结构
     * @param tableCode
     * @return
     */
    DynaBean initSysTable(String tableCode);

    /**
     * 拼接指定表的所有列 字段的字符串     SY_CREATEUSER,SY_CREATETIME,SY_STATUS
     * @param resourceTable
     * @param excludes
     * @return
     */
    String getFieldNames(DynaBean resourceTable,String[] excludes);

    /**
     * 获取系统级别的查询字段(含主键)
     * 当需要查询局部字段的时候，使用此方法获取到所有系统级别，然后再根据资源表把需查询业务字段拼接
     * 如： 局部查询TEST_FIELD1,TEST_FIELD2和所有系统字段   "TEST_FIELD1,TEST_FIELD2,"+BeanUtils.getInstance().getSysQueryFields(表名)
     * @param tableCode
     * @return
     */
    String getSysQueryFields(String tableCode);

    /**
     * 获取业务级别的查询字段(不含主键)
     * 当需要局部查询业务字段数据时，使用此方法可以得到所有业务字段
     * 如：局部查询业务字段和主键    "主键,"+BeanUtils.getInstance().getSysQueryFields(表名)
     * @param tableCode 表名
     * @return 查询字段按逗号隔开
     */
    String getProQueryFields(String tableCode);

    /**
     * 获取查询字段
     * 当 需要查询所有字段想指定排除一些存储量大的字段，使用此方法可以完成操作
     * @param tableCode 表名
     * @param excludes 排除字段
     * @return 查询字段按逗号隔开
     */
    String getQueryFields(String tableCode,String[] excludes);

    /**
     * 获取不包含大文本的所有字段
     * 当需要查询数据用于操作时，一些大文本字段不会被操作和修改，则可以调用方法获取到查询字段(不包含大文本字段)
     * 大文本字段：MySql的text SQLServer的text Oracle的clob(clob字段尽量别查询，因为查询要构建值的过程需用到文件流，会暂用java的内存很大)
     * @param tableCode 表名
     * @return 查询字段按逗号隔开
     */
    String getNoClobQueryFields(String tableCode);

    /**
     * 得到树形模版对象
     * @param tableCode
     * @return
     */
    JSONTreeNode getTreeTemplate(String tableCode);

    /**
     * 构建dyanBean的树形模版类
     * 排除bean的大文本字段
     * @param columns
     * @return
     */
    JSONTreeNode buildJSONTreeNodeTemplate(List<DynaBean> columns);

}
